

#include <iostream.h>

int IoStream_HardwareInput(IoStream_t *stream, uint8_t b)
{
    return (RingBuffer_Write(& stream->rxRBuf, & b) == 0) ? 1 : 0;
}

static int _Put(void *instance, unsigned char b)
{
    IoStream_t *stream;

    stream = instance;
    return stream->output(instance, & b, 1);
}

static int _Get(void *instance, uint8_t *pb)
{
    IoStream_t *stream;

    stream = instance;
    return RingBuffer_Read(& stream->rxRBuf, pb);
}

static unsigned int _Write(void *instance, const void *bp, unsigned int n)
{
    IoStream_t *stream;

    stream = instance;
    return stream->output(instance, bp, n);
}

static unsigned int _Read(void *instance, void *bp, unsigned int n)
{
    IoStream_t *stream;
    unsigned int m;
    uint8_t *vdata;

    stream = instance;
    vdata = bp;
    m = 0;
    while(n--)
    {
        if(RingBuffer_Read(& stream->rxRBuf, vdata++) == 0)
        {
            m += 1;
        }
        else
        {
            break;
        }
    }

    return m;
}

static const struct BaseStreamVMT _vmt = {_Write, _Read, _Put, _Get};

void IoStream_Init(
        IoStream_t *stream,
        void *buf,
        unsigned int bufSize,
        IoStream_Output_t output,
        void *userData)
{
    stream->vmt = & _vmt;
    stream->_rxBuf = buf;
    stream->userData = userData;
    stream->output = output;

    RingBuffer_Init(& stream->rxRBuf, buf, bufSize);
    RingBuffer_SetFlags(& stream->rxRBuf, RINGBUFFER_FLAG_OVERWRITE);
}

void IoStream_ClearRxBuffer(IoStream_t *stream)
{
    RingBuffer_Clear(& stream->rxRBuf);
}
